package com.goodlearning.gloriamobile.activity;

import java.util.ArrayList;
import java.util.List;

import org.json.simple.JSONArray;
import org.json.simple.JSONObject;

import android.content.Context;
import android.content.DialogInterface;
import android.graphics.Color;
import android.graphics.drawable.ColorDrawable;
import android.os.Bundle;
import android.os.Handler;
import android.view.LayoutInflater;
import android.view.MotionEvent;
import android.view.View;
import android.view.ViewGroup;
import android.view.Window;
import android.webkit.CookieManager;
import android.webkit.CookieSyncManager;
import android.webkit.WebSettings;
import android.webkit.WebSettings.LayoutAlgorithm;
import android.webkit.WebView;
import android.widget.AbsListView;
import android.widget.AbsListView.OnScrollListener;
import android.widget.AdapterView;
import android.widget.Button;
import android.widget.ListView;
import android.widget.ProgressBar;
import android.widget.TextView;
import android.widget.Toast;

import com.goodlearning.gloriamobile.R;
import com.goodlearning.gloriamobile.adapter.CustomAdapter;
import com.goodlearning.gloriamobile.adapter.CustomAdapter.IListItemController;
import com.goodlearning.gloriamobile.commons.AutoScaleDialog;
import com.goodlearning.gloriamobile.commons.Constants;
import com.goodlearning.gloriamobile.commons.Utils;
import com.goodlearning.gloriamobile.commons.WebClientManager;
import com.goodlearning.gloriamobile.customview.ButtonGroup;
import com.goodlearning.gloriamobile.dto.GetNoticeResultDto;
import com.goodlearning.gloriamobile.net.JsonRequestThread.INetSuccessCallback;
import com.goodlearning.gloriamobile.net.JsonServiceRequester;
import com.goodlearning.gloriamobile.net.JsonWrapper;
/**
 * 공지사항 Activity
 * @author rapty54
 *
 */
public class Notification extends BaseActivity {

	private ButtonGroup orgBg;
	
	GetNoticeResultDto getNoticeResultDto;
	
	ArrayList<GetNoticeResultDto> getNoticeResultDtos;
	
	CustomAdapter<GetNoticeResultDto> customAdapter;
	
	ListView listView;
	
	int requestTimeCount,showWebViewCount,showWideViewPortNoti=0;
	
	int noticePageCount=1;
	
	private AutoScaleDialog autoScaleDialog;
	
	private ProgressBar progressBar;
	
	private int[] orgBtnIdxs = {
			R.id.campus_tab_Button,
			R.id.join_tab_Button,
			R.id.bookCafe_tab_Button};
	
	private WebView webView;
	
	View footer;
	
	Button popupclose;
	
	private boolean mLockListView;
	
	JSONArray jsonArray;
	
	private LayoutInflater layoutInflater;
	
	TextView footerText;
	
	int visibleCount,pos;
	
	int loadedItems,curPosition;
	
	@Override
	protected void onCreate(Bundle savedInstanceState) {
		super.onCreate(savedInstanceState);
		setContentView(R.layout.notification_body_layout);
		
		getNoticeResultDtos=new ArrayList<GetNoticeResultDto>();
		
		mLockListView=true;
		
		curPosition=0;
		
		init();
	}
	
	public void init(){
		Utils.log("==========================================init============================");
		baseTitleLeftBtn.setVisibility(View.INVISIBLE);
		baseTitleRightBtn.setVisibility(View.INVISIBLE);
		baseTitleTv.setText("공지사항");
		listView=(ListView)findViewById(R.id.notification_result_ListView);
		
		Utils.setPreference(Notification.this, "Button_key","0");
		
		if(mLockListView==true){
//			addfooterView(R.layout.footer);
//			footerText=(TextView)findViewById(R.id.textLabel);
//			footerText.setOnTouchListener(new View.OnTouchListener() {
//				
//				@Override
//				public boolean onTouch(View v, MotionEvent event) {
//					return true;
//				}
//			});
//			footerText.setText("마지막 페이지입니다.");
		}else if(mLockListView==false){
//			footerText.setText("불러오는중 ....");
		}
		
		/**
		 * TabButton 정의 (Tab 에 대한 Listen)
		 * 각 Tab 에 대해  Adapter 갱신을 비롯하여  
		 */
		orgBg = new ButtonGroup(this, orgBtnIdxs, true);
		
		Utils.log("Button Idx:"+"["+orgBg.getCheckedButtonIdx()+"]");
		
		orgBg.setOnCheckedChangeListener(new ButtonGroup.OnCheckedChangeListener() {
			
			@Override
			public void onCheckedChange(Button button) {
				
				Utils.log("Button:"+"["+button.getId()+"]"+"||"+"Button Idx:"+"["+orgBg.getCheckedButtonIdx()+"]");
				
				switch (orgBg.getCheckedButtonIdx()) {
				case 0:
					
					if(getNoticeResultDtos.size()!=0){
						setVisibleEmptyArea(false);
//						footerText.setText("불러오는중 ....");
						setRequestKeyValue(String.valueOf(orgBg.getCheckedButtonIdx()));
						requestGetEachPageNoticeList(Utils.getStringByPreference(Notification.this, "Button_key", ""),noticePageCount);
						customAdapter.clear();
					}else{
						setVisibleEmptyArea(true);
						break;
					}
					
					break;
				case 1:
					
					if(getNoticeResultDtos.size()!=0){
						setVisibleEmptyArea(false);
//						footerText.setText("불러오는중 ....");
						setRequestKeyValue(String.valueOf(orgBg.getCheckedButtonIdx()));
						requestGetEachPageNoticeList(Utils.getStringByPreference(Notification.this, "Button_key", ""),noticePageCount);
						customAdapter.clear();
					}else{
						setVisibleEmptyArea(true);
						break;
					}
					break;
				case 2:
					
					if(getNoticeResultDtos.size()!=0){
						setVisibleEmptyArea(false);
//						footerText.setText("불러오는중 ....");
						setRequestKeyValue(String.valueOf(orgBg.getCheckedButtonIdx()));
						requestGetEachPageNoticeList(Utils.getStringByPreference(Notification.this, "Button_key", ""),noticePageCount);
						customAdapter.clear();
					}else{
						setVisibleEmptyArea(true);
						break;
					}
					break;
				default:
					break;
				}
			}
		});
	}
	
	/**
	 * OnResume 쪽에 초기 실행해야할 사항을 넣은 이유는 OnCreate 부분에서 최초 1회 시작후
	 * 전체 Activity 에 대한 종료를 시도 하게 될때 다시 OnCreate 이 호출되면서 반복적으로 Service 를 요청함으로써
	 * System 에 문제 발생ㅎ할수 있다. 이쪽 에서 제어  하였다. 
	 */
	@Override
	protected void onResume() {
		super.onResume();
		requestTimeCount++;
		Utils.log("=============onResumeActiviatedCount==========="+"["+requestTimeCount+"]");
		responseOnResumeState(requestTimeCount);
	}
	/**
	 * LifeCycle 에 따라서 초기에 요청 및 실행될 Service 를 요청한다.
	 * OnResume 즉 외부로 나갔다 다시 해당 APP 에 진입했을시에 다시 재실행 방지를 위해
	 * 한번만 실행한다. 어차피 UI 에 출력되는 사항들은 기본적으로 저장이 되기에 연속적인 호출은 필요 없다.
	 * 
	 * @param resumeCount
	 */
	public void responseOnResumeState(int resumeCount){
		if(resumeCount==1){
			requestGetEachPageNoticeList(Utils.getStringByPreference(Notification.this, "Button_key", ""),noticePageCount);
		}
	}
	/**
	 * TabButton 클릭시에 추가 되는 키값 
	 * 각 키값 설정후에 Adapter 리스트 내부에 포함되어있는 객체 전부를 지운다 그래야 새로운 리스트를 연속적으로 
	 * 불러다 사용 할 수 있기 때문이다.
	 */
	public void setRequestKeyValue(String key){
		noticePageCount=1;
		Utils.setPreference(Notification.this, "Button_key","");
		Utils.setPreference(Notification.this, "Button_key",key);
	}
	
	/**
	 * Adapter 부분에서 ArrayList 에서 Add 하는 부분을 현재 함수 내부에 선언할수 없다 .
	 * 이유는 전체가 지양하는 List 에 각 매 요청이 올때마다 각자의 리스트를 포함시켜서 리스트에 추가 시켜주어야 하는 이유 때문이다.
	 * 내부에 선언을 하게 되면 리스트를 새로 갱신을 하여도 List 개별의 객체로 만들어서 추가 하기때문에 추가가 되지 않는다. 
	 * 리스트 추가후 화면 갱신 기능  스크롤에 어떤 특정 반응 이벤트가 반응 할때 
	 * @param noticeType 페이지 타입 (캠퍼스,취업,북카페) 0/1/2 로 구분
	 * @param noticepage 각 페이지 타입의 요청할 페이지 수 넘김. 
	 */
	public void requestGetEachPageNoticeList(final String noticeType,final int noticepage){
		
		Utils.log("noticeType:"+"["+noticeType+"]"+"noticepage:"+"["+noticepage+"]");
		
		JsonServiceRequester.requestGetNoticeList(Notification.this, noticeType , noticepage, new INetSuccessCallback() {
			
			@Override
			public void sendCallback(JsonWrapper jsonWrapper) {
				
				 jsonArray=jsonWrapper.getRootArray();
				
				for(int i=0 ;i<jsonArray.size();i++){
					
					JSONObject jsonObject=(JSONObject)jsonArray.get(i);
					
					getNoticeResultDto=new GetNoticeResultDto();
					
					getNoticeResultDto.setIdx(Utils.convertObjToString(jsonObject.get("idx")));
					getNoticeResultDto.setNoticePage(noticeType);
					getNoticeResultDto.setPart(Utils.convertObjToString(jsonObject.get("part")));
					getNoticeResultDto.setTitle(Utils.convertObjToString(jsonObject.get("title")));
					getNoticeResultDto.setFilename(Utils.convertObjToString(jsonObject.get("filename")));
					getNoticeResultDto.setRegdate(Utils.convertObjToString(jsonObject.get("regdate")));
					getNoticeResultDto.setWriter(Utils.convertObjToString(jsonObject.get("writer")));
					getNoticeResultDto.setTotalPage(Utils.convertObjToString(jsonObject.get("totalpage")));
					
					getNoticeResultDtos.add(getNoticeResultDto);
				}
					
					setVisibleEmptyArea(getNoticeResultDtos.size()<=0);
					
					mLockListView=false;
					
					if(jsonArray.size()<=0){
						mLockListView=true;
//						footerText.setText("마지막 페이지입니다.");
					}else{
						mLockListView=false;
//						footerText.setText("불러오는중 ....");
						Utils.log("List_Size_Each_Position:"+getNoticeResultDtos.size());
					}
					Utils.log("First_Visible_Position:"+"["+pos+"]");
					
					customAdapter=new CustomAdapter<GetNoticeResultDto>(Notification.this, R.layout.notification_list_result_row, getNoticeResultDtos, itemController);
//					customAdapter.notifyDataSetChanged();
					
					listView.setAdapter(customAdapter);
							
					Utils.log("Adapter_Total_Count:"+"["+customAdapter.getCount()+"]");
					
					int listPosition=customAdapter.getCount()-2;
					
					Utils.log("list_position:"+"["+listPosition+"]");

					/**
					 * 현재 리스트뷰에서 처리 해주어야할 부분
					 */
					Utils.log("GetIDX:"+"["+orgBg.getCheckedButtonIdx()+"]"+"["+curPosition+"]");
					listView.setSelection(listView.getLastVisiblePosition());
					listView.setOnItemClickListener(onItemClickListener);
					listView.setOnScrollListener(onScrollListener);
//					customAdapter.notifyDataSetChanged();
					Utils.log("ArrayList_Total_Size:"+"["+jsonArray.size()+"]");
					
				}
			
		});
	}
	
	/**
	 * OnScrollListener 따로 분리
	 * ScrollView Scroll 시에 리스트에 보여지는 뷰 끝에 다 았을경우에
	 * Event 발생 시점    
	 */
	OnScrollListener onScrollListener=new OnScrollListener() {
		
		@Override
		public void onScrollStateChanged(AbsListView view, int scrollState) {
			
		}
		@Override
		public void onScroll(AbsListView view, int firstVisibleItem,int visibleItemCount, int totalItemCount) {
			
			Utils.log("VISIBLE_ITEM_COUNT:"+"["+visibleItemCount+"]"+"TOTAL_ITEM_COUNT:"+"["+totalItemCount+"]");
			
			Utils.log("========="+"["+"first : "+firstVisibleItem+" items : "+visibleItemCount+" last : "+totalItemCount+"]");
			
			visibleCount=firstVisibleItem;
			
			Utils.log("Visible_Count:"+"["+visibleCount+"]");
			
			int count = totalItemCount - visibleItemCount;
			
			loadedItems=firstVisibleItem +visibleItemCount;
			
			Utils.log("loadedItems:"+"["+loadedItems+"]");
			
			if(firstVisibleItem >= count && totalItemCount != 0 && mLockListView == false && getNoticeResultDtos.size()>0){
			      Utils.log("Loading next items");
			      
			      Utils.log("loadedItems:"+"["+loadedItems+"]");
			      
			      addItem();
			      
			 }
			
			}
		
	};
	
	/**
	 * 추가적으로 Runnable 을 다로 동작 구현을 분리 하였다 여러대의 타종 단말에서
	 * 발생할수 있는 문제를 최소화 하기 위해서 모두 로딩시의 작업과 서버에 요청 하는 값 또한 각자의 동작 별로 따로 분리 히였다.
	 * 여기서의 가장 핵심은 mLockListView Flag 이다 이 변수가 하는 역할은 ArrayList 에 각 Item 들이 추가 될시에 
	 * Lock 을 건다는 것이다. Lock 이 걸려있을 동안은 중복으로 Data 를 요청 한다거나  하는 예외가 발생되는 문제들 방지이며 또한 구현 방법 중 하나이다.
	 * delay 를 주어서 불러오는중이라는 표기를 한번 보여주고 바로 요청한다.  
	 */
	
	public void addItem(){
		mLockListView = true;
		noticePageCount++;
		
		Runnable runnable=new Runnable() {
			
			@Override
			public void run() {
				requestGetEachPageNoticeList(Utils.getStringByPreference(Notification.this, "Button_key", ""), noticePageCount);
//				removeFooterView(R.layout.footer);
			}
		};
		Handler handler=new Handler();
		handler.postDelayed(runnable, 800);
	}
	
	/**
	 * Footer 추가
	 */
	public void addfooterView(int Resource){
			layoutInflater=(LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
			listView.addFooterView(layoutInflater.inflate(Resource, null));
	}
	
	/**
	 * Footer 삭제
	 */
	public void removeFooterView(int Resource){
		
//		listView.removeFooterView(layoutInflater.inflate(Resource, null));
	}
	
	/**
	 * List controller 
	 */
	IListItemController<GetNoticeResultDto> itemController=new IListItemController<GetNoticeResultDto>() {

		@Override
		public View controlView(List<GetNoticeResultDto> items, int position,View convertView, ViewGroup parent) {
			
			GetNoticeResultDto getNoticeResultDto=(GetNoticeResultDto)items.get(position);
		
			String getPart;
			
			if(getNoticeResultDto.getPart().equals("")){
				getPart="전체";
				Utils.log("================전체============");
			}else{
				getPart=getNoticeResultDto.getPart();
				Utils.log("================"+"["+getPart+"]"+"=============");
			}
			
			((TextView)convertView.findViewById(R.id.notification_state_regdate_and_writer_row_TextView)).setText(getPart+"|"+getNoticeResultDto.getRegdate()+"|"+getNoticeResultDto.getWriter());
			((TextView)convertView.findViewById(R.id.notification_title_row_TextView)).setText(StringReplace(getNoticeResultDto.getTitle()));
			
			return convertView;
		}
	};
	
	/**
	 * AdpaterView 에서의 이벤트 처리 부분 리스트에서 눌렀을째  Activity 진입 모드와 Dialog 모드 두가지가 존재 한다.
	 * Activity 일때는 각 객체 형태별로 값을 전달 해야 함으로 Parcelable 값을 저장했다.
	 * 
	 */
	AdapterView.OnItemClickListener onItemClickListener=new AdapterView.OnItemClickListener() {

		@Override
		public void onItemClick(AdapterView<?> parent, View view, int position,long id) {
			
				Utils.log("==============Each Item_Click===========");
				
				
				GetNoticeResultDto getNoticeResultEachRowDto=new GetNoticeResultDto();
				
				Utils.log("IDX:"+"["+((GetNoticeResultDto)parent.getItemAtPosition(position)).getIdx()+"]"
						+"NoticePage:"+"["+((GetNoticeResultDto)parent.getItemAtPosition(position)).getNoticePage()+"]");
				
				getNoticeResultEachRowDto.setIdx(((GetNoticeResultDto)parent.getItemAtPosition(position)).getIdx());
				getNoticeResultEachRowDto.setNoticePage(((GetNoticeResultDto)parent.getItemAtPosition(position)).getNoticePage());
				getNoticeResultEachRowDto.setPart(((GetNoticeResultDto)parent.getItemAtPosition(position)).getPart());
				getNoticeResultEachRowDto.setTitle(((GetNoticeResultDto)parent.getItemAtPosition(position)).getTitle());
				getNoticeResultEachRowDto.setFilename(((GetNoticeResultDto)parent.getItemAtPosition(position)).getFilename());
				getNoticeResultEachRowDto.setRegdate(((GetNoticeResultDto)parent.getItemAtPosition(position)).getRegdate());
				getNoticeResultEachRowDto.setRegdate(((GetNoticeResultDto)parent.getItemAtPosition(position)).getWriter());
				getNoticeResultEachRowDto.setWriter(((GetNoticeResultDto)parent.getItemAtPosition(position)).getTotalPage());
				
				Utils.log("FILE_PATH:"+"["+getNoticeResultEachRowDto.getFilename()+"]");
				
				notificationDetailPopup
						(getNoticeResultEachRowDto.getFilename()
						,getNoticeResultEachRowDto.getIdx()
						,getNoticeResultEachRowDto.getNoticePage());
				
				}
	};

	
	/**
	 * WebView PopUp 처리
	 * 각 리스트에서의 이벤트 처리후 팝업을 띄운다.
	 */
	
	public void notificationDetailPopup(String getNoticeResultDtoFileName,String idx,String noticePage){
		
		CookieSyncManager.createInstance(this);
		CookieSyncManager.getInstance().startSync();
		
		autoScaleDialog = new AutoScaleDialog(Notification.this);
		autoScaleDialog.requestWindowFeature(Window.FEATURE_NO_TITLE);
		autoScaleDialog.getWindow().setBackgroundDrawable(new ColorDrawable(Color.TRANSPARENT));
		autoScaleDialog.setContentView(R.layout.notification_webview_popup);
		startWebView(autoScaleDialog,idx, noticePage, R.id.notofication_dialog_detail_content_WebView, R.id.notification_dialog_progress_web_01);
		autoScaleDialog.show();
		
		popupclose.setOnClickListener(new View.OnClickListener() {

			@Override
			public void onClick(View v) {
				
				CookieSyncManager.getInstance().stopSync();
				CookieManager cookieManager = CookieManager.getInstance();
				cookieManager.removeAllCookie();
				
				autoScaleDialog.dismiss();
			}
		});	
			/**
			 * 팝업 변경 (기존 팝업에 대한 컴플레인 부분 수정 요청)
			 */
			if(!getNoticeResultDtoFileName.equals("")){
				Utils.showConfirmNoticeDialog(Notification.this, "", "첨부파일이 존재하는 공지입니다.\n첨부 파일 확인은 웹사이트를 이용해 주십시요.");
			}
			
			
	}
	
	/**
	 * http://www.androidpub.com/136987
	 * WebView 확대와 축소 ( 아이폰은 자동 설정 OPTION 간단한 설정 만으로도 옵션이 바로 적용이 된다.)
	 * 안드로이드에서는 webSettings (WebSettings.ZoomDensity.CLOSE) 외에 OPTION WebSettings.ZoomDensity.FAR,WebSettings.ZoomDensity.MEDIUM
	 * WebView 에 있는 setInitialScale(26) 이부분은 배율 확대를 의미한다. 함부로 쓸수 없다. 
	 * http://www.questionhub.com/StackOverflow/3916330
	 * Dialog 내부의 WebView 보여줌 
	 * <주의 사항 Dialog 내부의 View 에 보여져야 함으로 Dialog 에 포함된 View ID 를 가져와야 한다.>
	 * 현재 팝업 레이아웃은 FrameLayout 에 모두 같이 걸려 있음으로 초기화 모두 함께 해준다 안해주면 CastException 발생한다.
	 * webSettings.setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN); WebView 보여 질때 사이즈 문제 최소한의 조치 차원
	 * @param autoScaleDialog
	 * @param idx
	 * @param noticePage
	 * @param resouce
	 * @param progress
	 * @param count
	 */
	
	public void startWebView(AutoScaleDialog autoScaleDialog,String idx , String noticePage , int resouce, int progress) {
		
		showWebViewCount++;
		
		Utils.log("showWebViewCount:"+showWebViewCount);
		
		webView = (WebView)autoScaleDialog.findViewById(resouce);
		popupclose = (Button) autoScaleDialog.findViewById(R.id.closeBTN);
		progressBar = (ProgressBar)autoScaleDialog.findViewById(progress);
		
		webView.clearCache(true);
		webView.setWebViewClient(new WebClientManager(Notification.this,progressBar, webView,showWebViewCount));
		webView.setInitialScale(4);
		
		WebSettings webSettings = webView.getSettings();
		webSettings.setLayoutAlgorithm(LayoutAlgorithm.SINGLE_COLUMN);
		webSettings.setJavaScriptEnabled(true);
		webSettings.setJavaScriptCanOpenWindowsAutomatically(true);
		webSettings.setSaveFormData(true);
		webSettings.setSavePassword(true);
		webSettings.setUseWideViewPort(true);
		webSettings.setLoadWithOverviewMode(true);
		webSettings.setDefaultZoom(WebSettings.ZoomDensity.CLOSE);
		webSettings.setBuiltInZoomControls(true);
		
		Utils.log("Request Webview By Url:"+"["+Constants.Request_URL+"idx="+idx+"&"+"noticetype="+noticePage+"]");
		
		webView.loadUrl(Constants.Request_URL+"idx="+idx+"&"+"noticetype="+noticePage);
		webView.setVisibility(View.VISIBLE);
		webView.setOnTouchListener(new View.OnTouchListener() {
			
			@Override
			public boolean onTouch(View v, MotionEvent event) {
				
				if(showWideViewPortNoti==1){
					
					Toast.makeText(Notification.this, "화면을 두번 터치하면 화면비로 보기가 가능합니다.", Toast.LENGTH_SHORT).show();
					
				}
				
				showWideViewPortNoti++;
				
				return false;
			}
		});
	}
	
	
////	private int getScale(WebView webView){
//		 Display display = ((WindowManager) getSystemService(Notification.WINDOW_SERVICE)).getDefaultDisplay(); 
//		 int width = display.getWidth(); 
//		 Double val = new Double(width)/new Double(webView.getRight()-webView.getLeft());
//		 val = val * 100d;
//		 return val.intValue();
//		}
	
	/**
	 * 내가 제거 하고자 특정 Tag 선언후 제거 한다. 
	 * 나중에 추가적으로 어떤 특정 문자를 지워야 한다면 하나씩 추가해서 지운다.
	 * http://blog.naver.com/PostView.nhn?blogId=tyboss&logNo=70122462478&parentCategoryNo=6&viewDate=&currentPage=1&listtype=0
	 * @param str
	 * @return
	 */
	public static String StringReplace(String str){   
			
	      String match = "\\<.*?\\>";
	      
	      str = str.replaceAll(match, " ");
	      
	      if(str.contains("B")){
	    	  str =str.replace("B", "");
	    	  str =str.trim();
	      }else if(str.contains("b")){
	    	  str =str.replace("b", "");
	    	  str =str.trim();
	      }else if(str.contains("strong")){
	    	  str =str.replace("strong", "");
	    	  str=str.trim();
	      }
	      
	      return str;
	   }
	
	@Override
	public void onBackPressed() {
		
		Utils.showConfirmDialog(Notification.this, "종료", "글로리아 모바일을 종료 하시겠습니까?", new DialogInterface.OnClickListener() {
			
			@Override
			public void onClick(DialogInterface dialog, int which) {
				
				allClearActivity();
				
			}
		}, null);
	}

	
	
}
